package com.example.lib_leancloud

import androidx.lifecycle.MutableLiveData
import cn.leancloud.LCObject
import com.example.lib_leancloud.model.Advertisement
import com.example.lib_leancloud.model.Chart
import com.example.lib_leancloud.model.ChartMusicModel
import com.example.lib_leancloud.model.Music
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.random.Random

class LeanCloudManager private constructor() {
    var advertisementList: List<Advertisement> = emptyList()
    var chartList: List<Chart> = emptyList()
    var musicList: List<Music> = emptyList()
    private var isChartOk = false
    private var isMusicOk = false
    val chartMusicModelList = MutableLiveData<List<ChartMusicModel>>()

    private fun mergeMusic() {
        if (isMusicOk && isChartOk) {
            val chartMusicList = mutableListOf<ChartMusicModel>()
            instance.chartList.forEach { chart ->
                val musics = instance.musicList.filter { music ->
                    music.chart_id == chart.id
                }
                chartMusicList.add(ChartMusicModel(chart.name, musics))
            }
            chartMusicModelList.postValue(chartMusicList)
        }
    }

    companion object {
        val instance = LeanCloudManager()
    }

    fun loadAdv(callback: (LeanCloudManager, List<Advertisement>) -> Unit = { _, _ -> }) {

        CoroutineScope(Dispatchers.IO).launch {
            val query = LCObject.getQuery(Advertisement::class.java)

            val result = query.find()

            advertisementList = result

            withContext(Dispatchers.Main) {
                callback(this@LeanCloudManager, advertisementList)
            }
        }
    }

    fun getRandomAdv(): Advertisement {
        val index = Random.nextInt(advertisementList.size)
        return advertisementList[index]
    }

    fun loadCharts(callback: (LeanCloudManager, List<Chart>) -> Unit = { _, _ -> }) {

        CoroutineScope(Dispatchers.IO).launch {
            val query = LCObject.getQuery(Chart::class.java)

            val results = query.find()
            chartList = results
            isChartOk = true
            mergeMusic()
            withContext(Dispatchers.Main) {
                callback(this@LeanCloudManager, chartList)
            }
        }
    }

    fun loadAllMusic(callback: (List<Music>) -> Unit = {}) {

        CoroutineScope(Dispatchers.IO).launch {

            val query = LCObject.getQuery(Music::class.java)
            musicList = query.find()
            isMusicOk = true
            mergeMusic()
            withContext(Dispatchers.Main) {
                callback(musicList)
            }
        }
    }
}